#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int (*cmf_fn)(void *v1, void *v2);
int int_cmp(void *v1, void *v2)
{
	return *(int *)v1 - *(int *)v2;
}
int merge(void *array, int size, int start, int mid, int end, cmf_fn cmp)
{
	if (start == mid && mid == end) return 0;
	printf("start %d, mid %d, en %d\n", start, mid, end);
	int array_size = size*(end-start+1);
	void *tmp_array = malloc(array_size);
	int i = start, j = mid+1, k = 0;
	while (i <= mid && j <= end){
		if (cmp((char *)array+size*i, (char *)array+size*j) > 0){
			memcpy((char *)tmp_array+k*size,  (char *)array+size*j, size);
			k++; j++;
		} else {
			memcpy((char *)tmp_array+k*size,  (char *)array+size*i, size);
			k++; i++;

		}
	}
	while (j <= end)
		memcpy((char *)tmp_array+k++*size,  (char *)array+size*j++, size);
	while (i == mid)
		memcpy((char *)tmp_array+k++*size,  (char *)array+size*i++, size);
	for (i = 0; i < end-start+1; i++)
		printf("%d ", *(int *)((char *)tmp_array+i*size));
	printf("\n");
	memcpy((char *)array+start*size, tmp_array, array_size);
	free(tmp_array);
	return 0;
	
}
int divide(void *array, int size, int start, int end, cmf_fn cmp)
{
	int mid = (start+end)/2;
	if (start < end) {
		divide(array, size, start, mid, cmp);
		divide(array, size, mid+1, end, cmp);
	}
		merge(array, size, start, mid, end, cmp);
	return 0;
}
int merge_sort(void *array, int size, int len, cmf_fn cmp)
{
	if (!array || len < 2 || !cmp) return 0; 
	divide(array, size, 0, len-1, cmp);
	return 0;			
}
void main(void)
{
	int i;
	int a[] = {4,1,5,7,3,2,6};
	for (i = 0; i < 7; i++) 
		printf ("%d ", a[i]);
	printf("\n");
	merge_sort(a, sizeof(int), sizeof(a)/sizeof(int), int_cmp);
	for (i = 0; i < 7; i++) 
		printf ("%d ", a[i]);
	printf("\n");

}
